package com.mazaiting.generator.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mazaiting.common.core.domain.result.Option;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.BusinessException;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import com.mazaiting.generator.converter.IDatasourceConverter;
import com.mazaiting.generator.enums.DbTypeEnum;
import com.mazaiting.generator.config.GenDataSource;
import com.mazaiting.generator.domain.entity.DatasourceEntity;
import com.mazaiting.generator.domain.form.DatasourceForm;
import com.mazaiting.generator.domain.query.DatasourceQuery;
import com.mazaiting.generator.domain.vo.DatasourceVO;
import com.mazaiting.generator.mapper.IDatasourceMapper;
import com.mazaiting.generator.service.IDatasourceService;
import com.mazaiting.mybatisplus.domain.vo.BasePageVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 数据源管理
 *
 * @author mazaiting
 * @datetime 2022-11-01 18:40:51
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DatasourceServiceImpl extends ServiceImpl<IDatasourceMapper, DatasourceEntity> implements IDatasourceService {

    private final IDatasourceConverter datasourceConvert;

    @Override
    public BasePageVO<DatasourceVO> page(DatasourceQuery datasourceQuery) {
        // 分页数据
        Page<DatasourceEntity> page = lambdaQuery()
                .page(new Page<>(datasourceQuery.getPageNum(), datasourceQuery.getPageSize()));
        // entity -> vo
        Page<DatasourceVO> voPage = datasourceConvert.entity2VO(page);

        return BasePageVO.success(voPage);
    }

    @Override
    public boolean save(DatasourceForm datasourceForm) throws BusinessException {
        // 根据连接名查询
        Optional<DatasourceEntity> datasourceEntityOpt = lambdaQuery().eq(DatasourceEntity::getConnName, datasourceForm.getConnName()).oneOpt();
        if (datasourceEntityOpt.isPresent()) {
            throw new BusinessException(ResultCode.COMMON_FAIL.getCode(), "数据源连接名已存在, 请更换名称");
        }
        // form -> entity
        DatasourceEntity entity = datasourceConvert.form2Entity(datasourceForm);
        // 如果是选择的状态, 则要更新其他数据状态为 false
        if (entity.getSelected()) {
            lambdaUpdate()
                    .set(DatasourceEntity::getSelected, false)
                    .eq(DatasourceEntity::getSelected, true)
                    .update();
        }
        return save(entity);
    }

    @Override
    public boolean update(DatasourceForm datasourceForm) throws EmptyObjectException {
        // 根据 ID 查询查询实体
        DatasourceEntity entity = getById(datasourceForm.getId());
        if (Objects.isNull(entity)) {
            log.warn("实体不存在");
            throw new EmptyObjectException(ResultCode.COMMON_FAIL.getCode(), "数据源不存在");
        }
        // form -> entity
        datasourceConvert.form2Entity(datasourceForm, entity);
        // 如果是选择的状态, 则要更新其他数据状态为 false
        if (entity.getSelected()) {
            lambdaUpdate()
                    .set(DatasourceEntity::getSelected, false)
                    .eq(DatasourceEntity::getSelected, true)
                    .update();
        }
        return updateById(entity);
    }

    @Override
    public boolean deleteByIds(String ids) {
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
        return removeByIds(idList);
    }

    @Override
    public DatasourceVO getInfoById(Long id) {
        DatasourceEntity datasourceEntity = getById(id);
        if (Objects.isNull(datasourceEntity)) {
            log.warn("实体信息不存在");
        }
        return datasourceConvert.entity2VO(datasourceEntity);
    }

    @Override
    public GenDataSource getBySourceId(Long dataSourceId) throws Exception {
        // 初始化配置信息
        return new GenDataSource(getById(dataSourceId));
    }

    @Override
    public String getDatabaseProductName(Long dataSourceId) {
        // 默认是 Mysql
        if (dataSourceId == 0) {
            return DbTypeEnum.MySQL.name();
        } else {
            return getById(dataSourceId).getDbType();
        }
    }

    @Override
    public List<Option<Long>> listOptions() throws BusinessException {
        // 获取选项列表
        List<Option<Long>> optionList = lambdaQuery()
                .select(DatasourceEntity::getId, DatasourceEntity::getConnName)
                .list()
                .stream().map(entity -> new Option<>(entity.getId(), entity.getConnName())).toList();
        if (CollectionUtils.isEmpty(optionList)) {
            throw new BusinessException(ResultCode.COMMON_FAIL.getCode(), "无可用数据源, 请先添加数据源");
        }
        return optionList;
    }

//    @Override
//    public GenDataSource get(Long datasourceId) {
//        // 初始化配置信息
//        GenDataSource info = null;
//        if (datasourceId.intValue() == 0) {
//            try {
//                info = new GenDataSource(dataSource.getConnection());
//            } catch (SQLException e) {
//                e.printStackTrace();
//            }
//        } else {
//            info = new GenDataSource(this.getById(datasourceId));
//        }
//
//        return info;
//    }
//
//    @Override
//    public boolean save(DataSourceEntity entity) {
//        entity.setCreateTime(new Date());
//        return super.save(entity);
//    }
}